package com.rexolar.openapi.utlis;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.rexolar.openapi.constants.Constants;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;

/**
 * @author zhusiyu
 * @description: ValidDateUtil
 * @date 2019-12-25
 **/
@Slf4j
public class ValidDateUtil {


    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    /**
     * @param date yyyy-MM-dd HH:mm:ss
     * @param expireTime 有效时长  秒值
     * @return
     */
    public static boolean isValidDate(String date, int expireTime) {
        if (StringUtils.isBlank(date)) {
            return false;
        }
        //兼容老版本的字符串格式 时间
        if (date.contains(Constants.SYMBOL_COLON)) {
            return ValidDateUtil.isValidDateString(date, expireTime);
        } else {
            return ValidDateUtil.isValidTimestamp(Long.parseLong(date), expireTime * 1000);
        }

    }



    /**
     * 由于在最初设计时，时间戳格式为字符串；需要兼容旧版本的设计缺陷
     * @param date yyyy-MM-dd HH:mm:ss
     * @param expireTime 有效时长  秒值
     * @return
     */
    public static boolean isValidDateString(String date, int expireTime) {
        try {
            if (date.contains(Constants.SYMBOL_POINT)) {
                date = date.substring(0, date.indexOf(Constants.SYMBOL_POINT));
            }

            LocalDateTime dateTime = LocalDateTime.parse(date, DATE_FORMATTER);
            //为防止请求重返与时间的有效合法性，对时间戳进行校验
            long timestamp = dateTime.toEpochSecond(ZoneOffset.of("+8"));

            return ValidDateUtil.isValidTimestamp(timestamp, expireTime);

        } catch (Exception e) {
            log.error("ValidDateUtil$isValidDate exception date:"+date, e.getMessage());
            return false;
        }
    }

    /**
     * @param timestamp unix时间戳
     * @param expireTime 有效时长  秒值
     * @return
     */
    public static boolean isValidTimestamp(long timestamp, int expireTime) {


        long now = System.currentTimeMillis();

        long min = now - expireTime;
        long max = now + expireTime;

        if(timestamp >= min && timestamp <= max ) {
            return true;
        } else {
            log.error("[{}] now:{}, timestamp:{}, expireTime:{}, timestamp >= min[{}]:{} , timestamp <= max[{}]:{}",
                    LocalDateTime.now() , now, timestamp, expireTime, min,timestamp >= min, max, timestamp <= max);
            return false;
        }
    }
}
